/*
 *  Copyright (c) 2009, Hugo Augusto Alves
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *      * Redistributions of source code must retain the above copyright
 *        notice, this list of conditions and the following disclaimer.
 *      * Redistributions in binary form must reproduce the above copyright
 *        notice, this list of conditions and the following disclaimer in the
 *        documentation and/or other materials provided with the distribution.
 *      * Neither the name of the Hugo Augusto Alves nor the
 *        names of its contributors may be used to endorse or promote products
 *        derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 *  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
 *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.wiscriptor.internalization;

import java.io.FileInputStream;
import java.util.ArrayList;
import org.ini4j.Ini;
import org.wiscriptor.io.FileLoader;
import org.wiscriptor.utils.Utils;

/**
 *
 * @author Hugo
 */
public class I18N {

    private static I18N instance;
    private ArrayList<Language> langs = new ArrayList<Language>();
    private String language = "";
    private String country = "";
    private boolean isAllLanguagesLoaded = false;
    private boolean isLanguageLoaded = false;
    private Ini ini = null;

    public static enum key {

        menuFile,
        menuOptions,
        menuTools,
        menuHelp,
        menufileNew,
        menufileSave,
        menufileSaveAs,
        menufileOpen,
        menufileExit,
        menuoptionsLanguage,
        menutoolsLoremIpsum,
        menuhelpAbout,
        tabsViewer,
        tabsEditor,
        tabsSettings,
        navigationMain,
        navigationCreate,
        navigationRandom,
        navigationAll,
        navigationSearch,
        stringOK,
        stringCancel,
        stringNewFile,
        stringYes,
        stringNo,
        stringApply,
        stringsavefileTitle,
        stringsavefileMessage,
        stringopenfileTitle,
        stringopenfileMessage,
        stringloremWindowTitle,
        stringloremTextType,
        stringloremWordCount,
        stringloremParagraphCount,
        stringloremVerseCount,
        stringloremStanzaCount,
        stringloremGeneralText,
        stringloremPoetryText,
        stringloremErrorInputTitle,
        stringloremErrorInput,
        settingsName,
        settingsTab01,
        settingsTab02,
        settingsTab03,
        settingserrorTitle,
        settingserrorMessage,
        settingslafTitle,
        settingslangTitle,
        wikisTitle,
        windowNameBox,
        windowOmniBox,
        windowCategories
    }

    private I18N() {
    }

    public static I18N getInstance() {
        instance = (instance == null) ? new I18N() : instance;
        return instance;
    }

    public ArrayList<Language> getAvailableLanguages() {
        if (isAllLanguagesLoaded) {
            return langs;
        }
        String[] fList = null;
        try {
            fList = FileLoader.getInstance().loadFile("languages").list();
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        if (fList == null) {
            return null;
        }
        for (String s : fList) {
            try {
                Ini aux = new Ini(new FileInputStream(FileLoader.getInstance().loadFile("languages", s)));
                String name = aux.get(Language.FIELD_INFO, Language.INFO_NAME);
                String l = aux.get(Language.FIELD_INFO, Language.INFO_LANGUAGE);
                String c = aux.get(Language.FIELD_INFO, Language.INFO_COUNTRY);
                langs.add(new Language(name, l, c));
            } catch (Exception ex) {
                ex.printStackTrace();
                return null;
            }
        }
        isAllLanguagesLoaded = true;
        return langs;
    }

    public void load(String language, String country) {
        this.language = language;
        this.country = country;
        if (!isAllLanguagesLoaded) {
            getAvailableLanguages();
        }
        try {
            int index = Utils.indexOfLanguages(language, country, langs);
            ini = new Ini(new FileInputStream(FileLoader.getInstance().loadFile("languages", getFileName(langs.get(index)))));
            isLanguageLoaded = true;
        } catch (Exception ex) {
            isLanguageLoaded = false;
            ex.printStackTrace();
        }
        /*
        for (String key : ini.get("menu.file").keySet()) {
        System.out.println("menu.file/" + key + " = " + ini.get("menu.file").fetch(key));
        }
         */
    }

    private void reLoad() {
        if (!isLanguageLoaded) {
            load(language, country);
        }
    }

    public String getValueForKey(key k) {
        reLoad();
        // Error on getting ini file
        if (ini == null) {
            return "";
        }
        switch (k) {
            case menuFile:
                return ini.get("menu", "File");
            case menuOptions:
                return ini.get("menu", "Options");
            case menuTools:
                return ini.get("menu", "Tools");
            case menuHelp:
                return ini.get("menu", "Help");
            case menufileNew:
                return ini.get("menu.file", "New");
            case menufileSave:
                return ini.get("menu.file", "Save");
            case menufileSaveAs:
                return ini.get("menu.file", "SaveAs");
            case menufileOpen:
                return ini.get("menu.file", "Open");
            case menufileExit:
                return ini.get("menu.file", "Exit");
            case menuoptionsLanguage:
                return ini.get("menu.options", "Language");
            case menutoolsLoremIpsum:
                return ini.get("menu.tools", "LoremIpsum");
            case menuhelpAbout:
                return ini.get("menu.help", "About");
            case tabsViewer:
                return ini.get("tabs", "Viewer");
            case tabsEditor:
                return ini.get("tabs", "Editor");
            case tabsSettings:
                return ini.get("tabs", "Settings");
            case navigationMain:
                return ini.get("navigation", "Main");
            case navigationCreate:
                return ini.get("navigation", "Create");
            case navigationAll:
                return ini.get("navigation", "All");
            case navigationRandom:
                return ini.get("navigation", "Random");
            case navigationSearch:
                return ini.get("navigation", "Search");
            case stringOK:
                return ini.get("string", "OK");
            case stringCancel:
                return ini.get("string", "Cancel");
            case stringNewFile:
                return ini.get("string", "NewFile");
            case stringYes:
                return ini.get("string", "Yes");
            case stringNo:
                return ini.get("string", "No");
            case stringApply:
                return ini.get("string", "Apply");
            case stringsavefileTitle:
                return ini.get("string.savefile", "Title");
            case stringsavefileMessage:
                return ini.get("string.savefile", "Message");
            case stringopenfileTitle:
                return ini.get("string.openfile", "Title");
            case stringopenfileMessage:
                return ini.get("string.openfile", "Message");
            case stringloremWindowTitle:
                return ini.get("string.lorem", "WindowTitle");
            case stringloremTextType:
                return ini.get("string.lorem", "TextType");
            case stringloremWordCount:
                return ini.get("string.lorem", "WordCount");
            case stringloremParagraphCount:
                return ini.get("string.lorem", "ParagraphCount");
            case stringloremVerseCount:
                return ini.get("string.lorem", "VerseCount");
            case stringloremStanzaCount:
                return ini.get("string.lorem", "StanzaCount");
            case stringloremGeneralText:
                return ini.get("string.lorem", "GeneralText");
            case stringloremPoetryText:
                return ini.get("string.lorem", "PoetryText");
            case stringloremErrorInputTitle:
                return ini.get("string.lorem", "InputTitle");
            case stringloremErrorInput:
                return ini.get("string.lorem", "ErrorInput");
            case settingsName:
                return ini.get("settings", "Name");
            case settingsTab01:
                return ini.get("settings", "Tab01");
            case settingsTab02:
                return ini.get("settings", "Tab02");
            case settingsTab03:
                return ini.get("settings", "Tab03");
            case settingserrorTitle:
                return ini.get("settings.error", "Title");
            case settingserrorMessage:
                return ini.get("settings.error", "Message");
            case settingslafTitle:
                return ini.get("settings.laf", "Title");
            case settingslangTitle:
                return ini.get("settings.lang", "Title");
            case wikisTitle:
                return ini.get("wikis", "Title");
            case windowNameBox:
                return ini.get("window", "NameBox");
            case windowOmniBox:
                return ini.get("window", "OmniBox");
            case windowCategories:
                return ini.get("window", "Categories");
        }
        return "";
    }

    // TODO: pegar a extensão do arquivo em propriedades
    private String getFileName(String language, String country) {
        return language + "-" + country + ".lng";
    }

    private String getFileName(Language l) {
        return l.getLang() + "-" + l.getCountry() + ".lng";
    }
}
